package com.demo.common.base;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.demo.common.base.entity.BaseEntity;
import com.demo.common.base.entity.PageQueryEntity;
import com.demo.common.constant.Constant;
import com.demo.common.enums.RoleOrgTypeEnum;
import com.demo.common.utils.ShiroUtils;
import com.demo.common.utils.SpringContextUtils;
import com.demo.modules.sys.entity.SysOrgEntity;
import com.demo.modules.sys.entity.SysRoleEntity;
import com.demo.modules.sys.entity.SysUserEntity;
import com.demo.modules.sys.service.SysOrgService;
import com.demo.modules.sys.service.SysUserRoleService;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 基础查询条件构造器封装
 *
 * @author Mark sunlightcs@gmail.com
 */
public class QueryBase<T extends BaseEntity> extends Query<T> {
    private static SysOrgService sysOrgService;
    private static SysUserRoleService sysUserRoleService;

    static {
        sysOrgService = (SysOrgService) SpringContextUtils.getBean("orgService");
        sysUserRoleService = (SysUserRoleService) SpringContextUtils.getBean("sysUserRoleService");
    }

    /**
     * 根据数据权限封装查询参数
     *
     * @param wrapper   条件构造器
     * @param queryForm 查询表单对象
     * @return 查询条件构造器
     */
    public LambdaQueryWrapper<T> getQuery(LambdaQueryWrapper<T> wrapper, PageQueryEntity queryForm) {
        // 获取当前用户
        SysUserEntity user = ShiroUtils.getUserEntity();

        // 超级管理员
        if (user.getId() == Constant.SUPER_ADMIN) {
            return wrapper;
        }

        // 定义当前用户能查看的组织
        Set<Long> orgIds = new HashSet<>();
        orgIds.add(0L);

        // 查询用户角色列表
        List<SysRoleEntity> roles = sysUserRoleService.queryRoleList(user.getId());

        // 角色为空
        if (CollectionUtil.isEmpty(roles)) {
            wrapper.in(T::getOrgId, orgIds);
            return wrapper;
        }

        // 角色数据类型集合
        Set<Integer> roleOrgTypes = new HashSet<>();
        roles.forEach(role -> roleOrgTypes.add(role.getRoleOrgType()));

        // 角色包含全部数据
        if (roleOrgTypes.contains(RoleOrgTypeEnum.ALL.getValue())) {
            return wrapper;
        }

        // 角色包含本级及下级数据
        if (roleOrgTypes.contains(RoleOrgTypeEnum.SELF_CHILDREN.getValue())) {
            orgIds.add(user.getOrgId());
            List<SysOrgEntity> allChildren = sysOrgService.queryAllChildren(user.getOrgId());
            allChildren.forEach(org -> orgIds.add(org.getId()));
        }

        // 角色仅包含本级数据
        if (roleOrgTypes.contains(RoleOrgTypeEnum.SELF.getValue())) {
            orgIds.add(user.getOrgId());
        }

        wrapper.in(T::getOrgId, orgIds);

        return wrapper;
    }
}
